/*
 * scanner that tokenizes the input
 */

#include <stdio.h>
#include <regex.h>
#include <stdlib.h>
#include <string.h>

#define TRUE 1
#define FALSE 0



/**************************
**  Function Prototypes  **
***************************/
void parseWord(int s, int e);
int isDelimiter(char c);

/**************************
**  Global Vars          **
***************************/
char* buffer;
FILE *input_file;
FILE *output_file;




main() {
char* line;

char* fn = "input";

int LINE_MAX = 500;

int i = 0;
int start = 0, end = 0;

char tmp[50];



// open files for read/write
sprintf(tmp, "%s%s", fn, ".txt");
input_file = fopen(tmp, "r");
sprintf(tmp, "%s%s%s", fn, "_converted", ".txt");
output_file = fopen(tmp, "w");





if (input_file) // if file exists
{
	// get size of file
	fseek(input_file, 0, SEEK_END);
	int size = ftell(input_file);
	rewind(input_file);


	buffer = malloc(size);
	fread(buffer, 1, size-1, input_file);
	buffer[size] = '\0';
	int len = strlen(buffer);
	//for (int i = 0; i < len; i++)
		printf("%s", buffer);

	printf("\n");
	printf("The size of the file is %d\n", size);


fclose(input_file);

// now that it's loaded in the buffer, we can start tokenizing

	for (i = 0; i < size; ++i)
	{


	// old method (4/12 ~12am)
	/*
		if ( (buffer[i] == ' ') || (buffer[i] == '\0') )
		{
			printf("I got here, %c %d %c\n", buffer[i], i, buffer[start]);
			end = i-1;
			if (buffer[start] == ' ') start++;
			if (start > end) end = start;
			parseWord(start, end);
			start= i+1;
			end = i+1;
		}
		else if (buffer[i] == ';')
		{
			end = i-1;
			parseWord(start, end);
			start = i;
			end = i;
			parseWord(start, end);
			start = i+1;
			end = i+1;
		}
	*/


		// newer method using isDelimiter (4/12 ~3am)

		if (isDelimiter(buffer[i]))
		{
			//printf("The delimiter is %c\n", buffer[i]);
			end = i-1;
			if (end < start) end = start;
			parseWord(start, end);
			
			if ( (start != end) || (start != i) ) parseWord(i, i);
			start = i+1;
			end = i+1;
		}


	}

}

printf("\n");
fclose(output_file);
}



void parseWord(int s, int e)
{
int i = 0;
int idcheck = TRUE;

//printf("start: %d, end: %d\n", s, e);
char* tmpstr = malloc(e-s+2);
strncpy(tmpstr, buffer+s, e-s+1);

tmpstr[e-s+1] = '\0';
//printf("The String is %s %d\n", tmpstr, (int)strlen(tmpstr));

if (strcmp(tmpstr, "+") == 0)
{
	printf("PLUS\n");
	fprintf(output_file, "PLUS ");
}
else if (strcmp(tmpstr, "-") == 0)
{	
	printf("MINUS\n");
	fprintf(output_file, "MINUS ");
}
else if (strcmp(tmpstr, "(") == 0)
{
	printf("LEFTPAR\n");
	fprintf(output_file, "LEFTPAR ");
}
else if (strcmp(tmpstr, ")") == 0)
{
	printf("RIGHTPAR\n");
	fprintf(output_file, "RIGHTPAR ");
}
else if (strcmp(tmpstr, ":=") == 0)
{
	printf("ASSIGN\n");
	fprintf(output_file, "ASSIGN ");
}
else if (strcmp(tmpstr, "end") == 0)
{
	printf("END\n");
	fprintf(output_file, "END ");
}
else if (strcmp(tmpstr, "begin") == 0)
{
	printf("BEGIN\n");
	fprintf(output_file, "BEGIN ");
}
else if (strcmp(tmpstr, ";") == 0)
{
	printf("SEMICOLON\n");
	fprintf(output_file, "SEMICOLON ");
}
else if (strcmp(tmpstr, "%") == 0)
{
	printf("MODULO\n");
	fprintf(output_file, "MODULO ");
}
else if (strcmp(tmpstr, "*") == 0)
{
	printf("MULTIPLY\n");
	fprintf(output_file, "MULTIPLY ");
}
else if (strcmp(tmpstr, "print") == 0)
{
	printf("PRINT\n");
	fprintf(output_file, "PRINT ");
}
else if (strcmp(tmpstr, "read") == 0)
{
	printf("READ\n");
	fprintf(output_file, "READ ");
}
else if (strcmp(tmpstr, ",") == 0)
{
	printf("COMMA\n");
	fprintf(output_file, "COMMA ");
}
else // test for ID and INTNUM
{
	idcheck = TRUE;
	char* endPtr = tmpstr;
	long int tmplong = strtol(tmpstr, &endPtr, 10);
	if (endPtr != tmpstr) // if the pointer hasn't moved, it's not a number
	{
		printf("INTNUM\n");
		fprintf(output_file, "INTNUM ");
	}
	else // last thing to check is ID
	{
		if (tmpstr[0] == '_')
		{	
			if ( (strlen(tmpstr) <= 10) && (strlen(tmpstr) >= 2) )
			{
				if (!isalnum(tmpstr[1])) idcheck = FALSE; //underscore must be followed by a letter or num
				for (i=2; i<(int)strlen(tmpstr); ++i)
					if ( (!isalnum(tmpstr[i])) && (tmpstr[i] != '_') )
						idcheck = FALSE;

			}
			if (idcheck)
			{
				printf("ID\n");
				fprintf(output_file, "ID ");
			}
		}
		else if (isalpha(tmpstr[0]) ) // first character must be a letter or underscore
		{
			//printf("the first character is %c\n", tmpstr[0]);
			if (strlen(tmpstr) <= 10)
			{
				for (i=1; i<(int)strlen(tmpstr); ++i)
					if ( (!isalnum(tmpstr[i])) && (tmpstr[i] != '_') )
						idcheck = FALSE;
			}
			if (idcheck)
			{
				printf("ID\n");
				fprintf(output_file, "ID ");
			}
		} 
	}


}


/*

if (s == e)
{
	switch(buffer[s])
	{
		case '+':
			//sprintf("%s %s", out, "PLUS");
			printf("PLUS\n");
			break;
		case '-':
			printf("MINUS\n");
			break;
		
	}
}
else if (s+1 == e) // mostly checking for assignment
{
	char* tmpstr = malloc(3);
	strncpy(tmpstr, buffer+s, 2);
	tmpstr[2] = '\0';
	printf("%s\n", tmpstr);
	if (strcmp(tmpstr, ":=") == 0)
		printf("ASSIGN\n");
}
*/
}

int isDelimiter(char c)
{

	switch(c)
	{
		case '+':
		case '-':
		case ' ':
		case '(':
		case ')':
		case ',':
		case ';':
		case '*':
		case '%':
		case '\0':
			return TRUE;
		default:
			return FALSE;
	}
}
